home *** CD-ROM | disk | FTP | other *** search
/ Your Choice 3 / Your Choice Software Collection 3.iso / prgmming / fsprite3 / fsprite3.doc < prev    next >
Text File  |  1994-04-28  |  34KB  |  754 lines

  1.  
  2.  
  3.     FastSPRITE3 - A Fast VGA Gamepack for Turbo Pascal Programmers
  4.     By Warren Steven Riley Jr.
  5.     Copyright 1992,1994
  6.  
  7.  
  8.  
  9.         I have always wanted to write games.  Even though IBM compatibles 
  10.     have never been perfectly suited for writing games they have always 
  11.     been the machine that I wanted to program for.  When the VGA standard 
  12.     became available I was thrilled.  The 320x200 mode was perfectly suited 
  13.     for game development.  256 colors made all the difference.  I soon 
  14.     realized it wasn't going to be as easy as I expected.  The VGA standard 
  15.     forced you to have software put every pixel of graphics on the screen 
  16.     manually.  This proved to be extremely s-l-o-w.  I looked everywhere 
  17.     for a set of programming routines that would be fast and expedite my 
  18.     game development process.  I couldn't really find anything at the time.  
  19.     So I began writing FastSPRITE.  FastSPRITE is a Turbo Pascal unit that 
  20.     is extremely fast.
  21.     I first messed around with writing routines in conventional 
  22.     assembly language.  The technique used involved a machine language 
  23.     routine that picked up a pixel from the sprite's data definition and 
  24.     after deciding how to mask it would put it's pixel in it's appropriate 
  25.     place.  This was good but then I came up with an idea to make it nearly 
  26.     twice as fast.  I compiled the sprites so the speed could be maximized.  
  27.     This created a noticeable improvement and speed and was the core of 
  28.     FastSPRITE.
  29.  
  30.     (Distribution and Registering info are at the end of this document)
  31.     --------------------------------------------------------------------
  32.     --------------------|Introduction|----------------------------------
  33.     --------------------------------------------------------------------
  34.     --------------------------------------------------------------------
  35.         
  36.     FSPRITE3.TPU is a Turbo Pascal 7.0 Unit that can be linked in to 
  37.     your Turbo Pascal programs to write games.  It includes a number of 
  38.     useful sprite and graphics functions that are essential to writing a 
  39.     good game.  The technique used to create sprites that are smooth and 
  40.     seamless involve creating two virtual screens.  These screens are the 
  41.     MID and BACK screens.  Using this three tier approach fast "Super 
  42.     Nintendo" graphics can be created.  These graphics are smooth and 
  43.     "flicker free".  Without the two extra virtual screens multi-maskable 
  44.     sprite(20+) games with a full background would not be easily 
  45.     maintained.  These two screens do immediately steal 128k of memory but 
  46.     are well worth it in the end.
  47.     The interface for the FSPRITE3 TPU is given in the file 
  48.     FSPRITE3.INT.  This file contains all the necessary information for 
  49.     writing a game using FSPRITE3.  First I will give a brief explanation 
  50.     of the usage of the sprite variables and functions.
  51.     Essentially all sprites in the shareware version of FSPRITE3 are 
  52.     stored in SPF files.  The format for these files is simple.  The X and 
  53.     Y sizes are stored in the first two bytes followed by a simple left to 
  54.     right top to bottom bit dump of the image.  The list of Sprites your 
  55.     program will use is stored in a text data file.  This text data file 
  56.     can have any name and simply lists each sprite on a separate line until 
  57.     all sprites are listed.
  58.  
  59.     The format is as follows:
  60.  
  61.     SPRITEXX.SPF
  62.     SAMPLEXX.SPF
  63.     MOONUNIT.SPF
  64.         etc.
  65.  
  66.     The next process optionally involves converting the data file to a 
  67.     PASCAL include file.  This step is not necessary and is gone over in 
  68.     detail later.
  69.     The first thing you introduce into your code is the SETGRAPH 
  70.     routine.  This does nothing more than initialize the 320x200 256 color 
  71.     mode.  It calls the interrupt to set up this graphics mode $13.  The 
  72.     READSPRITES(FILENAME) command follows and the file name it uses is the 
  73.     text data file listing all the sprite SPF files used in the game.  All 
  74.     of these files must reside in the current directory.  After all sprites 
  75.     have been loaded you issue the COMPILE command.  This doubles the speed 
  76.     of your sprites.  Even though this routine isn't absolutely necessary 
  77.     it is highly recommended.  At this point the sprites definitions are 
  78.     all loaded into the SPRITE data type and the compiled sprites are all 
  79.     loaded into the COMPILEDSPRITES data type.  The compiled sprites are 
  80.     actually little machine language programs that are created at run-time 
  81.     to speed up sprite usage.
  82.     Even though you have all the sprite "pictures" in memory you 
  83.     probably don't want to display all of them at the same time.  The 
  84.     SPRITE data type is merely a bank of sprite images.  The sprites you 
  85.     see on the screen work with a variable called ONSCREEN.  The ONSCREEN 
  86.     variable lists the sprites you are currently viewing.  You tell each 
  87.     ONSCREEN sprite where its definition is coming from in the SPRITES data 
  88.     bank.  You tell ONSCREEN.NUM which definition it is using, ONSCREEN.X 
  89.     and ONSCREEN.Y where that sprite will appear on the screen and 
  90.     ONSCREEN.ON if the sprite is visible or not.  It may sound a little 
  91.     confusing at first but makes sense as you work with it.  The variable 
  92.     OS contains the number of sprites that are being displayed on the 
  93.     screen.  The number of sprites on screen is one less that the last 
  94.     ONSCREEN[XXX] used where XXX is the number of the referenced ONSCREEN 
  95.     element.
  96.     After you have all this set up you load the palette when you use a 
  97.     palette different than the default.  READVGAPALETTE(FILENAME) is the 
  98.     routine to to read a palette from a file.  The file palette is a 
  99.     straight dump of 256 RGB values each RGB value being a byte a piece.  
  100.     Next you would probably want to load a background file from disk and 
  101.     put it in the 64k BACK screen.  After everything is ready in the main 
  102.     loop simply execute the SHOW command to update the sprites on the 
  103.     screen.  And with that you have complete game potential.
  104.  
  105.     --------------------------------------------------------------------
  106.     ----------------|Interface Breakdown|-------------------------------
  107.     --------------------------------------------------------------------
  108.     --------------------------------------------------------------------
  109.  
  110.     Here each part of the TPU interface will be explained and broken 
  111.     down.  First the complete interface will be shown and then each part 
  112.     will be broken down piece by piece.
  113.  
  114.     Unit FSPRITE3;
  115.  
  116.     interface
  117.     Uses crt,Dos;
  118.  
  119.     Const MaxSpriteMemSize=20000;    {Maximum Sprite Sizing}
  120.     SpritesCompiled:boolean=false;
  121.     FullScreenCopy:boolean=false;
  122.     TileMode:boolean=false;
  123.  
  124.     ALTKEY=8;
  125.     CTRLKEY=4;
  126.     LEFTSHIFTKEY=2;
  127.     RIGHTSHIFTKEY=1;
  128.     CAPSLOCK=64; NUMLOCK =32; SCROLLLOCK=16;
  129.  
  130.     type ColorValue = record RED,GREEN,BLUE: shortint; end;
  131.     PaletteType = array [0..255] of ColorValue;
  132.     SpriteGrid = Array [0..maxspritememsize] of byte;
  133.     SpriteGridPointer = ^SpriteGrid;
  134.     Sprite = record
  135.         Sx,Sy:byte;
  136.         Def:SPRITEGRIDPOINTER;
  137.     end;
  138.     SpritePointer = ^Sprite;
  139.     GraphicScreen = Array[0..203,0..319] of byte;
  140.     ScreenPointer = ^GraphicScreen;
  141.     OnScreen_Part_Type=record num:word;on:boolean;x:integer;y:integer;end;
  142.     OnScreenType=Array[0..100] of OnScreen_Part_Type;
  143.  
  144.     var XKeyLocation:byte absolute $0040:$0017;
  145.     SpriteFileNames:ARRAY[0..200] OF STRING[12];
  146.     OS,NumberSpriteDefs:integer;
  147.     Sprites:Array[0..200] of SpritePointer;
  148.     OnScreen:OnScreenType;
  149.     Back,Mid:ScreenPointer;
  150.     Act:GraphicScreen absolute $A000:0000;
  151.     FKEY:array[0..255] of boolean;   {Array for keyboard buffer}
  152.  
  153.     Procedure killbuff;
  154.     Procedure startfkey;
  155.     Function xkey(LookFor:byte):boolean;
  156.     procedure Loadpalette(passname:string; var p:palettetype);
  157.     procedure SetVGAPalette(var tp:PaletteType);
  158.     procedure ReadVGApalette(var tp: PaletteType);
  159.     procedure SetGraph; Inline($B8/$13/0/$CD/$10);
  160.     procedure ReadSprites(FName:String);
  161.     procedure Compile;
  162.     procedure Show;
  163.  
  164.     Const MaxSpriteMemSize=20000;    {Maximum Sprite Sizing}
  165.  
  166.     This constant is the maximum size in byte that a sprite can 
  167.     possibly take up.
  168.  
  169.  
  170.  
  171.  
  172.  
  173.     ____________________________________________________________________
  174.     ------------------- CONSTANTS --------------------------------------
  175.     SpritesCompiled:boolean=false;
  176.  
  177.         This variable is TRUE when the sprites have been compiled FALSE 
  178.     otherwise.
  179.  
  180.     ____________________________________________________________________
  181.     FullScreenCopy:boolean=false;
  182.  
  183.     This variable is true when the entire middle screen will be lifted 
  184.     to the active screen in the SHOW routine.  Generally this variable is 
  185.     set to false at all times.  By only copying the sprites a better speed 
  186.     can be maintained.  The only time you would want to lift the entire MID 
  187.     screen is when almost all of its data is changing. 
  188.     ____________________________________________________________________
  189.     TileMode:boolean=false;
  190.  
  191.     Special mode not addressed at all in the shareware version.
  192.     ____________________________________________________________________
  193.     ALTKEY=8;
  194.     CTRLKEY=4;
  195.     LEFTSHIFTKEY=2;
  196.     RIGHTSHIFTKEY=1;
  197.     CAPSLOCK=64; NUMLOCK =32; SCROLLLOCK=16;
  198.  
  199.     These constants can be used in the FKEY extra key reading routine 
  200.     to reference their keys.  These "special" keys can be accessed by using 
  201.     their contents with the FKEY routine.
  202.  
  203.  
  204.  
  205.  
  206.     ____________________________________________________________________
  207.     ------------------ TYPES -------------------------------------------
  208.     type ColorValue = record RED,GREEN,BLUE: shortint; end;
  209.  
  210.     COLORVALUE is a type used for each entry in the palette. It is the 
  211.     generic RGB holder for 256 color paletted modes.  Each R,G,B can hold a 
  212.     value from 0 to 63.
  213.     ____________________________________________________________________
  214.     PaletteType = array [0..255] of ColorValue;
  215.     
  216.     A type that includes an entire VGA working palette.
  217.     ____________________________________________________________________
  218.     SpriteGrid = Array [0..maxspritememsize] of byte;
  219.  
  220.     The SPRITEGRID is basically a straight array of sprite data used by 
  221.     each SPRITES[XX].DEF entry.
  222.     ____________________________________________________________________
  223.     SpriteGridPointer = ^SpriteGrid;
  224.  
  225.     SPRITEGRIDPOINTER is the actual dynamically allocated pointer that 
  226.     is used by each SPRITES[XX].DEF entry.  Each sprite only allocates as 
  227.     much memory as it uses.  The dynamic approach is absolutely necessary  
  228.     so that no room is wasted.
  229.     ____________________________________________________________________
  230.     Sprite = record
  231.         Sx,Sy:byte;
  232.         Def:SPRITEGRIDPOINTER;
  233.         end;
  234.     
  235.     The Sprite data type is where sprites read in using the 
  236.     READSPRITES[FILENAME] procedure are stored before they are compiled.  
  237.     It allocates their X and Y sizes and their definition pointer.
  238.     ____________________________________________________________________
  239.     SpritePointer = ^Sprite;
  240.  
  241.     SpritePointer is the data type that establishes a dynamic pointer 
  242.     link with the SPRITE record.    
  243.     ____________________________________________________________________
  244.     GraphicScreen = Array[0..203,0..319] of byte;
  245.  
  246.     This is the basic screen type for accessing screen data.    
  247.     ____________________________________________________________________
  248.     ScreenPointer = ^GraphicScreen;
  249.  
  250.     This is a pointer.
  251.     ____________________________________________________________________ 
  252.     OnScreen_Part_Type=record num:word;on:boolean;x:integer;y:integer;end;
  253.  
  254.     The ONSCREEN array uses this type for each individual on-screen 
  255.     sprite.
  256.     ____________________________________________________________________ 
  257.     OnScreenType=Array[0..100] of OnScreen_Part_Type;
  258.     This type is for the ONSCREEN variable.
  259.  
  260.  
  261.  
  262.  
  263.     ____________________________________________________________________
  264.     -----------------  VARIABLES ---------------------------------------
  265.     var XKeyLocation:byte absolute $0040:$0017;
  266.  
  267.     This location is where the extra key presses are stored.  It is 
  268.     used by the XKEY routine.
  269.     ____________________________________________________________________ 
  270.     SpriteFileNames:ARRAY[0..200] OF STRING[12];
  271.  
  272.     This array stores the names of the actual sprites read in by 
  273.     READSPRITES(FILENAME) in the order they were read in.  It has a one to 
  274.     one correlation with the SPRITES[XX] variable.
  275.     ____________________________________________________________________ 
  276.     OS,NumberSpriteDefs:integer;
  277.  
  278.     The OS variable holds the number of active (on and off) ONSREEN 
  279.     elements.  It's number is equal to the last ONSCREEN[XX] value used. 
  280.  
  281.     The NUMBERSPRITEDEFS variable records the number of sprite 
  282.     definitions that were read in using the READSPRITES[FILENAME] routine.
  283.     ____________________________________________________________________ 
  284.     Sprites:Array[0..200] of SpritePointer;
  285.  
  286.     SPRITES is the actual array of sprite pointer where the sizex, 
  287.     sizey and sprite definition is stored.
  288.     ____________________________________________________________________ 
  289.     OnScreen:OnScreenType;
  290.  
  291.     ONSCREEN is the actual variable that holds the information on the 
  292.     sprites currently on the screen including definition number, X 
  293.     position, Y position, etc.
  294.     ____________________________________________________________________ 
  295.     Back,Mid:ScreenPointer;
  296.  
  297.     These variables are the dynamic links to the extra screens used to 
  298.     hold graphic screen information necessary for the "flicker free" set- 
  299.     up.
  300.     ____________________________________________________________________ 
  301.     Act:GraphicScreen absolute $A000:0000;
  302.  
  303.     This is the actual array used for all the active screen sprite 
  304.     activity.  It points to the beginning of graphics memory.
  305.     ____________________________________________________________________ 
  306.     FKEY:array[0..255] of boolean;   {Array for keyboard buffer}
  307.  
  308.     This is an array that is used to detect keypresses using the FKEY 
  309.     routine.  Once FKEY is intialized it can detect keypressed of all keys, 
  310.     even when more than one key is being pressed simultaneously.
  311.  
  312.  
  313.  
  314.     ____________________________________________________________________
  315.     ----------Procedures and Functions----------------------------------
  316.     Procedure killbuff;
  317.  
  318.     This procedure must be used once the FKEY interrupt routines are 
  319.     started to "suck up" the extra keypresses.
  320.     ____________________________________________________________________ 
  321.     Procedure startfkey;
  322.  
  323.     This procedure starts the FKEY interrupt routines that allow 
  324.     sophisticated keypress routines for games to be implemented.  It can 
  325.     check for multiple keypresses and doesn't have a buffer.  When you use 
  326.     it the FKEY variable is constantly updated to tell you all the keys 
  327.     that are being pressed at exactly that instant.
  328.     ____________________________________________________________________ 
  329.     Function xkey(LookFor:byte):boolean;
  330.  
  331.     This is a special key handler that is built specifically for the 
  332.     shift, alt, ctrl and lock keys.  It can be emulated with FKEY but in 
  333.     some respects is even better for these particular keys.  Especially for 
  334.     lock states it is very useful.  You pass it a key to look for and it 
  335.     tells you TRUE or FALSE its state.
  336.     ____________________________________________________________________ 
  337.     procedure Loadpalette(passname:string; var p:palettetype);
  338.  
  339.     This procedure loads the palette in passname string from disk into 
  340.     the p variable that is of palette type.
  341.     ____________________________________________________________________ 
  342.     procedure SetVGAPalette(var tp:PaletteType);
  343.  
  344.     This uses a palette type variable to set the current VGA palette.
  345.     ____________________________________________________________________ 
  346.     procedure ReadVGApalette(var tp: PaletteType);
  347.  
  348.     This reads the current VGA palette into a variable of palettetype.
  349.     ____________________________________________________________________ 
  350.     procedure SetGraph; Inline($B8/$13/0/$CD/$10);
  351.  
  352.     This initializes the 320x200 256 color graphics mode.
  353.     ____________________________________________________________________ 
  354.     procedure ReadSprites(FName:String);
  355.  
  356.     This routine read a sprite list in from a text data file using the 
  357.     names provided in that file to load SPF files into the SPRITES variable 
  358.     structure.
  359.     ____________________________________________________________________ 
  360.     procedure Compile;
  361.  
  362.     Compiles the sprites for maximum speed creating a machine language 
  363.     routine that handle sprite placement much more efficiently than a 
  364.     traditional machine language sprite data handler program.  The data and 
  365.     code are actually melded together.     
  366.     ____________________________________________________________________ 
  367.     procedure Show;
  368.  
  369.     Call this routine to update the latest sprite positions.
  370.  
  371.  
  372.     --------------------------------------------------------------------
  373.     ----------------|Technique & Theory|--------------------------------
  374.     --------------------------------------------------------------------
  375.     --------------------------------------------------------------------
  376.  
  377.     The FSPRITE3 routines are built to maximize performance while still 
  378.     giving flexibility.  They provide especially fast animation for games 
  379.     allowing overlapping sprites and easy use of background.
  380.     The root of the routines uses a three level screen structure, each 
  381.     level being 64k.  The first level is the BACK level and holds the 
  382.     background of the screen to be seen.  The second level is a MID screen 
  383.     where the background is restored and the fresh compiled sprite 
  384.     definitions are stamped.  By stamping these definitions on a screen 
  385.     that is not active "flicker" is eliminated.  The third screen is the    
  386.     ACTive screen and is the one that is actually seen.  The sprites are 
  387.     lifted from the MID screen to the ACTive screen and the process is 
  388.     done.  All of this takes place every time the SHOW routine is called.
  389.     Sprite utilization for the end program is reasonably 
  390.     straightforward.  A text data file must be constructed that contains 
  391.     the names of all the sprite definition files that are to be loaded in.  
  392.     This list can be turned into an include file for pascal compilation 
  393.     using the DAT2INC.EXE program provided.  Whenever you add new sprites 
  394.     to the text data file use DAT2INC.EXE.  The program only has one 
  395.     parameter and that is the name of the file to be converted.  Do not add 
  396.     the extension because DAT2INC assumes it.
  397.     Once this include file has been created use the Turbo Pascal 
  398.     include command to add it into your program.  Don't actually slap the 
  399.     text directly into your source; instead keep it as another file.  At 
  400.     some point you will update this file and it is easily dealt with as a 
  401.     separate include file.  By adding this file to your program you get the 
  402.     added bonus of being able to refer to sprites definitions directly by 
  403.     name.  For example say you had these SPF files used in your program:
  404.     FIREBALL.SPF
  405.     FIREBAL2.SPF
  406.     FIREBAL3.SPF
  407.     MAN1.SPF
  408.     MAN2.SPF
  409.     MAN3.SPF
  410.  
  411.     DAT2INC would make an include file that looks like this:
  412.  
  413.     CONST FIREBALL=0;
  414.           FIREBAL2=1;
  415.           FIREBAL3=2;
  416.           MAN1=3;
  417.           MAN2=4;
  418.           MAN3=5;
  419.  
  420.     Notice that the .SPFs do fall off.  By making this include file you 
  421.     can address sprite definitions in your code by name.  This is extremely 
  422.     useful when telling the active ONSCREEN sprites what they look like in 
  423.     ONSCREEN.NUM.  Make sure all the sprite files are in the same 
  424.     directory.  The registered version allows you to roll-up all the SPF 
  425.     files into one big file.
  426.     Now you are set.  In your code the next thing you must do is add 
  427.     the SETGRAPH to initialize the graphics mode.  After that you want to 
  428.     use the READSPRITES procedure to read your SPF files off the disk and 
  429.     into memory.  They are all stored in the SPRITES data array.  Using the 
  430.     COMPILE procedure after READSPRITES just about doubles the speed of 
  431.     your sprite code.  It does take memory, so in some cases may not be 
  432.     used.  I almost always use it.
  433.     It works by turning the sprite data into actual machine language 
  434.     code.  Each sprite has its own tiny, specially geared machine language 
  435.     program.  Most sprite routines use a machine language loop that is the 
  436.     same for every sprite and requires figuring out which pixels to mask 
  437.     and which not to mask.  This is a very small number of opcodes, but it 
  438.     is DONE EVERY SINGLE PIXEL.  Even when you repeat something minor, say  
  439.     10,000 times every step of animation, things start to slow down.  There 
  440.     is no figuring out with my routines.  Once compiled on the fly they 
  441.     know which pixel to use and which not to use.  Special attention paid 
  442.     to each and every sprite.  Isn't that nice.
  443.     The mask that sprites use is color 0, whatever that may be.  
  444.     Usually, by default it is black so if you actually want to display 
  445.     black assign another color in the palette to the RGB values of black.
  446.     Once all the sprites have been compiled you'll want to set up the 
  447.     background screen.  You can erase it or assign a graphics screen to it.  
  448.     If you erase it I find the easiest way to do so the most efficiently is 
  449.     to use the turbo pascal FILLCHAR routine.  This statement will clear 
  450.     the background screen:
  451.  
  452.     FILLCHAR(BACK^,320*200,0)
  453.  
  454.     Remember that the BACK screen is addressed BACK^ because it has 
  455.     been dynamically allocated using the NEW command in the FSPRITE3 TPU.  
  456.     Whenever you access the back or middle screens it will be through a 
  457.     pointer.  The active screen does not work this way, it is direct.
  458.  
  459.     The next step is to clear out the middle screen.  At this point I 
  460.     usually copy the zeros from the back screen:
  461.  
  462.     MID^:=BACK^
  463.  
  464.     The same is true for the active screen:
  465.  
  466.     ACT:=BACK^
  467.  
  468.     At this point you have a blank screen and some sprites loaded and 
  469.     compiled in memory.  Maybe you would load a bitmap screen from disk:
  470.  
  471.     procedure load_screen(filename:string;var inscreen:graphicscreen);
  472.     begin
  473.         ASSIGN (fFile, filename);  {Read Bitmap screen from file}
  474.         RESET (fFile, 1);
  475.         BLOCKREAD (fFile, BOGUS_BUFFER, 7);
  476.         BLOCKREAD (fFile, inscreen, 64000);
  477.         CLOSE (fFile);
  478.     end;
  479.     . . . . .
  480.  
  481.     load_screen('FILENAME',BACK^)
  482.  
  483.     In this case I loaded a bitmap that had been clipped out of 
  484.     AutoDesk Animator using a screen capture utility.  The save format for 
  485.     this utility stored an extra seven bytes before the actual bit map data
  486.     is read in.  A palette could then be loaded:
  487.  
  488.     PROCEDURE LOAD_PALETTE(FILENAME:STRING;VAR INPAL:PALETTETYPE);
  489.     BEGIN
  490.         ASSIGN (pfile, FILENAME);  {Read screen palette from disk}
  491.     RESET (pfile, 1);
  492.         BLOCKREAD (pfile, BOGUS_BUFFER, 7);
  493.         BLOCKREAD (pfile, INPAL, 768);
  494.     CLOSE (pfile);
  495.     END;
  496.     . . . . .
  497.  
  498.     LOAD_PALETTE('FILENAME',P);
  499.  
  500.     And then actually make it the active palette:
  501.  
  502.     SET_VGA_PALETTE(p);
  503.  
  504.     Because we load a bitmap screen to BACK^ we have to move it to the MID 
  505.     screen and the ACTive screen:
  506.  
  507.     MID^:=BACK^;
  508.     ACT:=BACK^;
  509.  
  510.     I wrote a new load_palette command above because the loaded palette 
  511.     also has a tossable header at the beginning.  At this point we are 
  512.     ready to start focusing on the sprites themselves.
  513.     We could next set up the sprites we would see onscreen:
  514.  
  515.     ONSCREEN[0].NUM:=MAN1;
  516.  
  517.     This statement tells the first sprite that is on the screen to get 
  518.     its information from definition number MAN1 where MAN1 is a constant 
  519.     our include file set to 3 earlier.
  520.  
  521.     ONSCREEN[0].ON:=TRUE;
  522.  
  523.     ON set to TRUE tells us that this sprite will be visible now.  When 
  524.     the sprite is turned off it can easily be set to false;
  525.  
  526.     ONSCREEN[0].X:=100;
  527.     ONSCREEN[0].Y:=100;
  528.  
  529.     This tells the SHOW routine that the first sprite will be at 
  530.     location 100,100.  We set up all the rest of the sprites in a similar 
  531.     manner:
  532.  
  533.     FOR I:=1 to 40 DO
  534.       BEGIN;
  535.         ONSCREEN[I].NUM:=FIREBALL;
  536.         ONSCREEN[I].X:=RANDOM(320);
  537.         ONSCREEN[I].Y:=RANDOM(200);
  538.         ONSCREEN[I].ON:=TRUE;
  539.       END;
  540.  
  541.     Here forty more sprites have been added and they all look like 
  542.     fireballs.  They start at random locations and are all turned ON.
  543.  
  544.     The last step needed before the main program loop can be entered is to 
  545.     set the number if onscreen sprite definitions so FSPRITE3 knows how 
  546.     many sprites to look through.
  547.  
  548.     OS:=40;
  549.  
  550.     This is one less than the actual number of sprites, or simply the 
  551.     last number addressed in the onscreen array(40).  Our sample program 
  552.     now only needs to call show to display them:
  553.     REPEAT;
  554.        FOR I:=1 TO 40 DO
  555.         BEGIN
  556.            INC(ONSCREEN[I].X,3);
  557.            IF ONSCREEN[I].X>320 THEN 
  558.             ONSCREEN[I].X:=-20;                
  559.         END;
  560.        SHOW;    
  561.     UNTIL KEYPRESSED;
  562.  
  563.     One consideration that must be kept in mind is that sprites will 
  564.     only erase their old positions if they are designed and moved with 
  565.     cleanup in mind.  If you have sprites that are going to skip three 
  566.     pixels every time they move their corresponding sprites must have at 
  567.     least a three pixel "clear" barrier or else they will trail and streak.
  568.     If a sprites definition is seen as D and clear spaces as - a sprite 
  569.     that wants to skip three pixels each round of movement would look like 
  570.     this:
  571.     
  572.     ---------------------------
  573.     ---------------------------
  574.     ---------------------------
  575.     ---DDDDDDDDDDDDDDDDDDDDD---
  576.         ---DDDDDDDDDDDDDDDDDDDDD---
  577.         ---DDDDDDD--------DDDDDD---
  578.     ---DDDDDDDDDDDDDDDDDDDDD---
  579.     ---------------------------
  580.     ---------------------------
  581.     ---------------------------
  582.  
  583.     The middle dashes represent a "see-through" piece of sprite in the 
  584.     middle.  If you decide you want to wildly move the sprites around or 
  585.     wish to forget about the buffer, you can but you have to manually clean 
  586.     up the sprite trails.
  587.  
  588.     This is a very simple set of code blocks but does demonstrate the 
  589.     necessary basic principles of FSPRITE3 game program design.
  590.  
  591.     --------------------------------------------------------------------
  592.     -------------|Registration|-----------------------------------------
  593.     --------------------------------------------------------------------
  594.     --------------------------------------------------------------------
  595.  
  596.     You are allowed a thirty day trial period to exam FSPRITE3 and see 
  597.     if you would like to register it.  After that period you will be 
  598.     required to register it.  When you register it you will receive:
  599.  
  600.         1 The latest 'registered' version of FSPRITE
  601.  
  602.         2 Additional functions and procedures unavailable in the shareware 
  603.       version
  604.  
  605.         3 A comprehensive manual describing FSPRITE's capabilities, syntax, 
  606.       descriptions, examples etc.
  607.  
  608.         4 A removal of all the 'nag' messages.
  609.  
  610.     5 More examples and all the other demonstration goodies that can      
  611.           fit on a disk (much more than can be distributed in a 'small'       
  612.       modem shareware file).
  613.  
  614.     6 A full registered version of the SPREDIT sprite editor program       
  615.           and everything that it's registered features entails.
  616.  
  617.     7 The ability to freely distribute the code you create from your       
  618.           programs built using FSPRITE for fun and of course profit
  619.  
  620.     8 The ability to write Borland Pascal code that use DPMI (dos            
  621.           protected mode interface) routines to break the one meg barrier.  
  622.           Using Borland Pascal I can easily write code that takes 4,5 or 6 
  623.       meg of ram!
  624.  
  625.         To register simply send $45 check or money order to:
  626.  
  627.             Steve Riley
  628.             P.O.Box #21
  629.             Herndon, VA 22070-9998
  630.  
  631.         Make check payable to Steve Riley.
  632.         Make sure and give us your full name and address.
  633.         Make sure and specify FSPRITE.
  634.     Make sure and specify disk format.
  635.     (If you choose 360k 5 1/4 inch floppy it will be mailed on two           
  636.         disks for an extra fee of one dollar)
  637.  
  638.     If you would like the actual source code to the FSPRITE3 unit 
  639.     itself send a total of $120 to the address above and you will also 
  640.     recieve the source code.
  641.  
  642.     --------------------------------------------------------------------
  643.     --------------------|DISTRIBUTION|----------------------------------
  644.     --------------------------------------------------------------------
  645.     --------------------------------------------------------------------
  646.  
  647.     These files may be freely distributed as long as all the files are 
  648.     distributed as is and intact.  All of the files must be present.  The 
  649.     file list is at the end of this DOC.  No profit can come from the sale 
  650.     of this product.  The only acceptable payment is reimbursement for 
  651.     distribution costs.  The non-shareware registered version of this 
  652.     product should never be given out under any circumstances.  The source 
  653.     code to the FSPRITE unit itself should never be given out under any 
  654.     circumstances.
  655.  
  656.     --------------------------------------------------------------------
  657.     --------------------|DISCLAIMER|------------------------------------
  658.     --------------------------------------------------------------------
  659.     --------------------------------------------------------------------
  660.  
  661.     FSPRITE3 is provided AS IS without any warranty, expressed or implied.
  662.     White Obsidian Software shall not be liable for ANY damages,
  663.     whether direct, indirect, special, or consequential arising from a
  664.     failure of this FSPRITE unit or accompanying files to operate in a 
  665.     manner desired by the user.  White Obsidian Software shall not be held 
  666.     responsible for any damage which may by caused by use of this unit or 
  667.     its accompanying files.  White Obsidian Software will not be held 
  668.     responsible for ANY damages related to the use of these files.
  669.  
  670.  
  671.     Enjoy,
  672.  
  673.             Steve Riley
  674.             April 29, 1994.
  675.  
  676.     Filelist:
  677.     FINDFKEY PAS         1,088 04-28-94   4:25a
  678.     BEGIN    BLD        64,007 02-16-92  12:44a
  679.     SCREEN00 BLD        64,007 02-15-92   8:51p
  680.     SCREEN01 BLD        64,007 02-15-92   5:17a
  681.     DIGIT    DAT             1 04-28-94   6:43a
  682.     ORDER    DOC         1,376 04-28-94   4:18a
  683.     README   DOC         5,228 04-28-94   4:56a
  684.     BEGIN    PLT           777 02-16-92  12:44a
  685.     SCREEN00 PLT           777 02-15-92   8:51p
  686.     SCREEN01 PLT           777 02-15-92   5:17a
  687.     GOBATME SMP         8,000 11-14-91   4:01a
  688.     FSPRITE3 DOC        30,700 04-28-94   6:19a
  689.     GOLIKEM1 SMP         6,000 11-14-91   6:20p
  690.     GOLIKEM2 SMP         6,000 11-14-91   3:02a
  691.     GOLIKEM3 SMP         6,000 11-14-91   5:16p
  692.     GOLIKEM4 SMP         6,000 11-14-91   5:17p
  693.     D        EXE        33,904 04-28-94   5:41a
  694.     REALBASE PAS        20,418 04-28-94   4:25a
  695.     FILE_ID  DIZ           311 04-28-94   5:11a
  696.     REALBOMB PAS         4,300 04-28-94   4:51a
  697.     BOMBER1  SPF           578 02-15-92   7:32p
  698.     BOMBER2  SPF           578 02-15-92   7:36p
  699.     BOMBER3  SPF           578 02-15-92   7:36p
  700.     BOMBER4  SPF           578 02-15-92   7:37p
  701.     BOOM1    SPF           427 02-14-92  11:45p
  702.     BOOM2    SPF           427 02-14-92  11:46p
  703.     BOOM3    SPF           427 02-14-92  11:46p
  704.     BOOM4    SPF           427 02-14-92  11:55p
  705.     BOX1     SPF           422 02-15-92  11:18p
  706.     BOX2     SPF           422 02-15-92  11:28p
  707.     BOX3     SPF           422 02-15-92  11:57p
  708.     BOX4     SPF           422 02-15-92  11:59p
  709.     GTEST    DAT           501 04-21-94   3:04a
  710.     ESPHERE1 SPF           427 02-15-92   8:21p
  711.     ESPHERE2 SPF           427 02-15-92   8:19p
  712.     ESPHERE3 SPF           427 02-15-92   8:18p
  713.     ESPHERE4 SPF           427 02-15-92   8:16p
  714.     EYE1     SPF           427 02-15-92   3:08p
  715.     EYE2     SPF           427 02-15-92   3:11p
  716.     EYE3     SPF           427 02-15-92   3:14p
  717.     EYE4     SPF           427 02-15-92   3:17p
  718.     REALVARS PAS        11,659 04-28-94   4:26a
  719.     FACE1    SPF           602 02-15-92   7:02p
  720.     FACE2    SPF           602 02-15-92   7:03p
  721.     FACE3    SPF           602 02-15-92   7:04p
  722.     FACE4    SPF           602 02-15-92   7:05p
  723.     FIGHTER  SPF           422 02-15-92   2:28a
  724.     FIGHTER1 SPF           422 02-15-92   9:00p
  725.     FIGHTER2 SPF           422 02-15-92   8:59p
  726.     FIGHTER3 SPF           422 02-15-92   9:06p
  727.     SPRDEVAL DOC        25,909 04-28-94   4:43a
  728.     LIVES    SPF           158 02-15-92   1:56p
  729.     MISSL    SPF            38 02-15-92   6:21a
  730.     MOTH1    SPF           422 02-15-92  11:18p
  731.     MOTH2    SPF           422 02-15-92  11:28p
  732.     MOTH3    SPF           422 02-15-92  11:57p
  733.     MOTH4    SPF           422 02-15-92  11:59p
  734.     PURPFIRE SPF            42 08-14-91   2:01p
  735.     LFIGHTER SPF           422 04-21-94   3:22a
  736.     SKULL    SPF           602 02-15-92   8:28p
  737.     SNAKBALL SPF           274 02-15-92   7:09p
  738.     SNAKHOLE SPF           274 02-15-92   7:10p
  739.     SPHERE1  SPF           427 02-15-92   6:14a
  740.     SPHERE2  SPF           427 02-15-92   6:15a
  741.     SPHERE3  SPF           427 02-15-92   6:15a
  742.     SPHERE4  SPF           427 02-15-92   6:16a
  743.     TEMP     SPF           427 02-15-92   5:57a
  744.     REALEVIL PAS         7,578 04-28-94   4:53a
  745.     VERTEBRA SPF           274 02-15-92   5:49a
  746.     RUNME    EXE        29,200 04-28-94   8:05p
  747.     DAT2INC  PAS           736 04-17-94   7:12p
  748.     DAT2INC  EXE         4,176 04-17-94   7:12p
  749.     GTEST    INC           664 04-21-94   3:04a
  750.     REALITY  PAS           856 04-28-94   4:24a
  751.     DBOMBER  SPF           578 04-21-94   8:10p
  752.     FSPRITE3 TPU        25,168 04-26-94   6:20a
  753.     FSPRITE3 INT         2,144 04-28-94   8:12p
  754.